/* * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Florent Guillaume */ package org.nuxeo.ecm.core.opencmis.impl; import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.EventListener; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.Servlet; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.xml.ws.WebServiceException; import org.apache.chemistry.opencmis.commons.SessionParameter; import org.apache.chemistry.opencmis.commons.enums.BindingType; import org.nuxeo.ecm.core.opencmis.bindings.LoginProvider; import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisContextListener; import org.nuxeo.runtime.test.runner.FeaturesRunner; import com.google.inject.Binder; import com.sun.xml.ws.api.server.Container; import com.sun.xml.ws.transport.http.DeploymentDescriptorParser; import com.sun.xml.ws.transport.http.DeploymentDescriptorParser.AdapterFactory; import com.sun.xml.ws.transport.http.ResourceLoader; import com.sun.xml.ws.transport.http.servlet.ServletAdapter; import com.sun.xml.ws.transport.http.servlet.ServletAdapterList; import com.sun.xml.ws.transport.http.servlet.WSServlet; import com.sun.xml.ws.transport.http.servlet.WSServletDelegate; /** * Feature that starts a Web Services session. */ public class CmisFeatureSessionWebServices extends CmisFeatureSessionHttp { public static final String JAXWS_XML = "/sun-jaxws.xml"; @Override public void configure(FeaturesRunner runner, Binder binder) { super.configure(runner, binder); setWebServices(); } // JavaUtilLoggingHelper.redirectToApacheCommons(); // JavaUtilLoggingHelper.reset(); @Override protected void setUpServer() throws Exception { // disable SOAP login checks System.setProperty(LoginProvider.class.getName(), TrustingLoginProvider.class.getName()); super.setUpServer(); } @Override protected void tearDownServer() throws Exception { super.tearDownServer(); System.clearProperty(LoginProvider.class.getName()); } @Override protected void addParams(Map<String, String> params) { String uri = serverURI.toString(); uri += "services/"; // from sun-jaxws.xml params.put(SessionParameter.BINDING_TYPE, BindingType.WEBSERVICES.value()); params.put(SessionParameter.WEBSERVICES_REPOSITORY_SERVICE, uri + "RepositoryService?wsdl"); params.put(SessionParameter.WEBSERVICES_NAVIGATION_SERVICE, uri + "NavigationService?wsdl"); params.put(SessionParameter.WEBSERVICES_OBJECT_SERVICE, uri + "ObjectService?wsdl"); params.put(SessionParameter.WEBSERVICES_VERSIONING_SERVICE, uri + "VersioningService?wsdl"); params.put(SessionParameter.WEBSERVICES_DISCOVERY_SERVICE, uri + "DiscoveryService?wsdl"); params.put(SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE, uri + "RelationshipService?wsdl"); params.put(SessionParameter.WEBSERVICES_MULTIFILING_SERVICE, uri + "MultiFilingService?wsdl"); params.put(SessionParameter.WEBSERVICES_POLICY_SERVICE, uri + "PolicyService?wsdl"); params.put(SessionParameter.WEBSERVICES_ACL_SERVICE, uri + "ACLService?wsdl"); } @Override protected Servlet getServlet() { return new WSServlet(); } @Override protected List<FilterAndName> getFilters() { return Collections.emptyList(); // XXX TODO } @Override protected EventListener[] getEventListeners() { return new EventListener[] { new NuxeoCmisContextListener(), new LocalWSServletContextListener() }; } /** * Loads a delegate configured for a local sun-jaxws.xml file. */ public static class LocalWSServletContextListener implements ServletContextListener { /** Delegate expected by WSServlet */ protected WSServletDelegate delegate; @Override public void contextDestroyed(ServletContextEvent event) { if (delegate != null) { delegate.destroy(); delegate = null; } } /* * Puts in the servlet context the proper delegate expected by WSServlet. */ @Override public void contextInitialized(ServletContextEvent event) { try { ServletContext context = event.getServletContext(); ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (cl == null) { cl = getClass().getClassLoader(); } ResourceLoader loader = new ServletContextResourceLoader(context); Container container = newServletContainer(context); AdapterFactory<ServletAdapter> adapterFactory = new ServletAdapterList(); DeploymentDescriptorParser<ServletAdapter> parser = new DeploymentDescriptorParser<ServletAdapter>(cl, loader, container, adapterFactory); URL endpoints = context.getResource(JAXWS_XML); if (endpoints == null) { throw new WebServiceException("No endpoints configured, missing file: " + JAXWS_XML); } List<ServletAdapter> adapters = parser.parse(endpoints.toExternalForm(), endpoints.openStream()); delegate = new WSServletDelegate(adapters, context); context.setAttribute(WSServlet.JAXWS_RI_RUNTIME_INFO, delegate); } catch (WebServiceException e) { throw e; } catch (Exception e) { throw new WebServiceException(e.toString(), e); } } protected Container newServletContainer(ServletContext context) throws Exception { // return new ServletContainer(context); // the ServletContainer class from JAX-WS RI is package-private doh! Class<?> klass = Class.forName("com.sun.xml.ws.transport.http.servlet.ServletContainer"); Constructor<?> ctor = klass.getDeclaredConstructor(ServletContext.class); ctor.setAccessible(true); return (Container) ctor.newInstance(context); } } // The ServletResourceLoader class from JAX-WS RI is package-private doh! public static final class ServletContextResourceLoader implements ResourceLoader { protected final ServletContext context; public ServletContextResourceLoader(ServletContext context) { this.context = context; } @Override public URL getResource(String path) throws MalformedURLException { return context.getResource(path); } @Override public URL getCatalogFile() throws MalformedURLException { // TODO catalog location return getResource("/WEB-INF/jax-ws-catalog.xml"); } @SuppressWarnings("unchecked") @Override public Set<String> getResourcePaths(String path) { return context.getResourcePaths(path); } } }